﻿using BootyBay.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BootyBay.Repository
{


    public class AppOperationRecordRepository
    {
        private AppOperationRecordRepository() { }
        static AppOperationRecordRepository _instance = new AppOperationRecordRepository();

        //create singlton instance
        public static AppOperationRecordRepository Instance()
        {

            return _instance;
        }

        RepositoryBase<AppOperationRecord> _repository = new RepositoryBase<AppOperationRecord>();
        public View_AppOptRecord4User InsertOptRecord(string userName, AppOperationType optType, int appInfoId)
        {
            AppOperationRecord newRecord = new AppOperationRecord()
            {
                TimeStamp = DateTime.UtcNow,
                Id_ApplicationInfo = appInfoId,
                OperationType = (int)optType,
                UserName = userName
            };

            var insertedRecord = _repository.Insert(newRecord);
            
            //TODO - test / query performance
            var viewModel = GetLastOptRecord(userName, appInfoId);
            return viewModel;
        }

        //public List<View_AppOperationRecord> GetLastOptRecordListForAllApps(string userName)
        //{
        //    var records = _repository.GetAll().Where(o => o.UserName == userName).OrderByDescending(o => o.TimeStamp)
        //        .GroupBy(o => new { o.Id_ApplicationInfo }).ToList().Select(g => new View_AppOperationRecord(g.FirstOrDefault()));

        //    return records.ToList();
        //}

        public View_AppOptRecord4User GetLastOptRecord(string userName, int appInfoId)
        {
            //TODO - test / query performance
            var model = GetAppOptRecord4User(userName).Where(r => r.Id_Application == appInfoId).FirstOrDefault();
            return model;
        }

        /// <summary>
        /// TODO: Potential bug.
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public List<View_AppOptRecord4User> GetAppOptRecord4User(string userName)
        {
            var userRecords = _repository.GetAll().Where(o => o.UserName == userName)
                .GroupBy(o => new { o.Id_ApplicationInfo }).Select(g => g.OrderByDescending(o => o.TimeStamp).FirstOrDefault());//.ToList();

            var appInfoRepo = new RepositoryBase<ApplicationInfo>( _repository.DbContext);
            var apps = appInfoRepo.GetAll(); //ApplicationInfoRepository.Instance().GetAll();//.ToList();

            var appVerInfoRepo = new RepositoryBase<ApplicationVersionInfo>(_repository.DbContext);
            var appVerInfos = appVerInfoRepo.GetAll();

            //var appArchRepo = new RepositoryBase<ApplicationProcessorArchitecture>(_repository.DbContext);
            //var appArchs = appArchRepo.GetAll();

            var q = from a in apps
                    join v in appVerInfos on a.Id equals v.Id_ApplicationInfo  
                    ///join t in appArchs on v.Id equals t.Id_ApplicationVersionInfo
                    join u in userRecords on a.Id equals u.Id_ApplicationInfo                    
                    into x
                    from y in x.DefaultIfEmpty() 
                    where v.Version == a.MajorVersion
                    select new View_AppOptRecord4User() //TODO - verify  
                    {
                        ApplicationName = a.ApplicationName,
                        Id_Application = a.Id,
                        OperationType = y == null ? AppOperationType.NA : (AppOperationType)y.OperationType,
                        UserName = y == null ? string.Empty : y.UserName,
                        LastUpdateTimeStamp = y == null ? DateTime.MinValue : y.TimeStamp,
                        MajorVersionPackageName = v.IdentityName,
                        MajorVersionPublisherName = v.Publisher,
                        AppProcessorArchitectureList =  v.ApplicationProcessorArchitectures.ToList(),
                        MajorVersion = v.Version,  
                        Id_AppOptRecord = y== null ? 0: y.Id
                    };

            var record = q.ToList();
            return record;
        }
    }

    //public class AppOperationRecordRepository<T> : RepositoryBase<T> where T : AppOperationRecord
    //{

    //}
}
